package org.netty.server.handler;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;

public class NettyServerHandler extends ChannelInboundHandlerAdapter {
	
    private Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);

    /**
     * 当客户端主动链接服务端的链接后，这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	// 当有客户端链接后，添加到channelGroup通信组
        ChannelHandler.channelGroup.add(ctx.channel());
        
        SocketChannel channel = (SocketChannel) ctx.channel();
        logger.info("connect report start");
        logger.info("connect report info: client connect");
        logger.info("connect report IP: " + channel.localAddress().getHostString());
        logger.info("connect report Port: " + channel.localAddress().getPort());
        logger.info("connect report end");
        
        // 通知客户端链接建立成功
        String str = "通知客户端链接建立成功" + " " + new Date() + " " + channel.localAddress().getHostString() + "\r\n";
        ctx.writeAndFlush(str);
        
        /**
         * 若没加编码处理器，发送数据时需要手动转换处理
         * ByteBuf buf = Unpooled.buffer(str.getBytes().length);
         * buf.writeBytes(str.getBytes("GBK"));
         */
    }

    /**
     * 当客户端主动断开服务端的链接后，这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // 当有客户端退出后，从channelGroup中移除
        ChannelHandler.channelGroup.remove(ctx.channel());
        logger.info("client disconnect: " + ctx.channel().localAddress().toString());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        /**
         * 若没加解码器，此处需要手动处理
         * ByteBuf buf = (ByteBuf) msg;
         * byte[] msgByte = new byte[buf.readableBytes()];
         * buf.readBytes(msgByte);
         * String str = new String(msgByte, Charset.forName("UTF-8"));
         */
        logger.info("server receive: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " " + msg);
        // 通知客户端链消息发送成功
        String str = "服务端收到：" + new Date() + " " + msg + "\r\n";
        ctx.writeAndFlush(str);
    }

    /**
     * 抓住异常，当发生异常的时候，可以做一些相应的处理，比如打印日志、关闭链接
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        logger.info("exception info: " + cause.getMessage());
    }
}
